import React, { useEffect, useState, useMemo, useContext, useRef, useCallback } from "react";
import { Button, Card, Form, Input, Space, Col, Row,message } from "antd";
import PromptBox from "../../components/ValidateBox/ProtoBox";
import Context from "./context";
import { setIcon } from "../../utils/setIcon";
import { drawVerfiCode } from "../../utils/canvasDraw";
import PinTu from "./PinTu";
import moment from 'moment' ;
import Axios from "axios";
import {connect} from 'react-redux';
function LoginForm({getUserInfo}) {
  const [form] = Form.useForm();
  // const [errorWord,setErrorWord] = useState(['','','']) // 本想写成这样子 但是发现和不自定义校验一样 不能在表单change事件的实时同步help框 而且不写form,直接提交 不会显示提示文案 antd对数组不太敏感
  const [nameerrorWord, setNameErrorWord] = useState(undefined);
  const [passworderrorWord, setPasswordErrorWord] = useState(undefined);
  const [verficationerrWord, setVerficationErrorWord] = useState(undefined);
  const [focusItem, setfocusItem] = useState(0);
  const { ele, dispatch } = { ...useContext(Context) };
  const [code, setCode] = useState([]);
  const [token,setToken] = useState('') ;
  const verCode = useRef();
  const nameicon = useMemo(() => {
    return setIcon(focusItem, nameerrorWord, 1);
  }, [focusItem, nameerrorWord]);
  const passwordicon = useMemo(() => {
    return setIcon(focusItem, passworderrorWord, 2);
  }, [focusItem, passworderrorWord]);
  const verficationicon = useMemo(() => {
    return setIcon(focusItem, verficationerrWord, 3);
  }, [focusItem, verficationerrWord]);
  const onFinish = (value) => {
    console.log(value);
  };

  const submit = () => {
    setfocusItem(0);
    form
      .validateFields()
      .then(async (values) => {
        let { data: res } = await Axios.post(`login`, {...values,ip:window.secretip,currentlogintime:moment().format('X')});
        console.log(res) ;
        if (res.ok == -1) {
          return setNameErrorWord((prev) => res.message);
        }
        if (res.ok == 0) {
          return setPasswordErrorWord((prev) => res.message);
        }
        if(res.ok == -2) {
          message.error(res.message) ;
          return 
        }
        if (code.join("") !== values.verfication.toLowerCase()) {
          setVerficationErrorWord((prev) => "验证码错误");
          return changeVer();
        }
         setToken(prev => res.token) ;
        console.log('hahhahha')
        let { data: ret } = await Axios.get("/ap/user");
        // console.log(res) ;
        if (ret.ok !== 0) {
          getUserInfo({ type: "getuser", data: ret.data });
          console.log(ret) ;
          // getUserInfo({type:'getHistory',history:history})
        }
        dispatch({ type: "sVisible", value: true });
      })
      .catch((errorInfo) => {
        console.log(errorInfo);
      });
  };
  // 自定义校验为的是数据表单数据一点改变 就会在改变时提示 不是只在失去焦点时提示
  const checkName = (rule, value, callback) => {
    return new Promise(async (reslove, reject) => {
      if (!value) {
        setNameErrorWord((prev) => "用户名不能为空");
        reject(new Error("用户名不能为空"));
      } else {
        if (!/^[a-zA-Z0-9_\u4e00-\u9fa5]+$/.test(value)) {
          setNameErrorWord((prev) => "不能有特殊的字符");
          reject(new Error("不能有特殊的字符"));
        } else {
          setNameErrorWord((prev) => "");
          reslove();
        }
      }
    });
  };
  const checkPassword = (rule, value, callback) => {
    return new Promise(async (reslove, reject) => {
      if (!value) {
        setPasswordErrorWord((prev) => "密码不能为空");
        reject(new Error("密码不能为空"));
      } else {
        if (!/^[a-zA-Z0-9_\u4e00-\u9fa5]+$/.test(value)) {
          setPasswordErrorWord((prev) => "不能有特殊的字符");
          reject(new Error("不能有特殊的字符"));
        } else {
          setPasswordErrorWord((prev) => "");
          reslove();
        }
      }
    });
  };
  const checkVerfication = (rule, value, callback) => {
    return new Promise(async (reslove, reject) => {
      if (!value) {
        setVerficationErrorWord((prev) => "验证码不能为空");
        reject(new Error("验证码不能为空"));
      } else {
        if (!/^[a-zA-Z0-9_\u4e00-\u9fa5]+$/.test(value)) {
          setVerficationErrorWord((prev) => "不能有特殊的字符");
          reject(new Error("不能有特殊的字符"));
        } else {
          setVerficationErrorWord((prev) => "");
          reslove();
        }
      }
    });
  };
  const changeVer = () => {
    const ctx = verCode.current.getContext("2d");
    let res = drawVerfiCode(ctx, 80, 40, []);
    setCode((prev) => res);
  };
  useEffect(() => {
    changeVer();
    // 拼图 画法 需要延迟执行 因为modal出现是异步的 需要js任务队列等待线程空闲再执行下面的函数 才能获取dom
    // console.log(res) ;
    // flag 必须写在这里 不然 setFlag 不会执行 ，页面不会更新
  }, [form]);
  return (
    <Card style={{ width: 400 }} title="登   录" bordered={false} className="loginform">
      <Form onFinish={onFinish} form={form} hideRequiredMark>
        <Form.Item
          hasFeedback
          validateStatus={nameicon}
          help={<PromptBox info={nameerrorWord}></PromptBox>}
          labelCol={{ span: 3, pull: focusItem === 1 ? 1 : 0 }}
          wrapperCol={{ span: 20, pull: focusItem === 1 ? 1 : 0 }}
          name="username"
          label={
            <span
              className="iconfont icon-user"
              style={{ color: "#a8a5a7", fontSize: "20px", opacity: focusItem === 1 ? 1 : 0.6 }}
            ></span>
          }
          rules={[{ validator: checkName }]}
          colon={false}
        >
          <Input
            placeholder="用户名"
            onFocus={() => {
              setfocusItem(1);
            }}
            onBlur={() => {
              setfocusItem(0);
            }}
          />
        </Form.Item>
        <Form.Item
          name="password"
          hasFeedback
          validateStatus={passwordicon}
          help={<PromptBox info={passworderrorWord}></PromptBox>}
          labelCol={{ span: 3, pull: focusItem === 2 ? 1 : 0 }}
          wrapperCol={{ span: 20, pull: focusItem === 2 ? 1 : 0 }}
          colon={false}
          label={
            <span
              className="iconfont icon-lock"
              style={{ color: "#a8a5a7", fontSize: "20px", opacity: focusItem === 2 ? 1 : 0.6 }}
            ></span>
          }
          rules={[{ validator: checkPassword }]}
        >
          <Input.Password
            placeholder="密码"
            onFocus={() => {
              setfocusItem(2);
            }}
            onBlur={() => {
              setfocusItem(0);
            }}
          />
        </Form.Item>
        <Form.Item
          hasFeedback
          help={<PromptBox info={verficationerrWord}></PromptBox>}
          validateStatus={verficationicon}
          labelCol={{ span: 3, pull: focusItem === 3 ? 1 : 0 }}
          colon={false}
          wrapperCol={{ span: 13, pull: focusItem === 3 ? 1 : 0 }}
          label={
            <span
              className="iconfont icon-icon_verification"
              style={{ color: "#a8a5a7", fontSize: "20px", opacity: focusItem === 3 ? 1 : 0.6 }}
            ></span>
          }
          name="verfication"
          rules={[{ validator: checkVerfication }]}
        >
          <Input
            placeholder="验证码"
            className="verfi"
            onFocus={() => {
              setfocusItem(3);
            }}
            onBlur={() => {
              setfocusItem(0);
            }}
          />
        </Form.Item>
        <canvas
          height="40"
          ref={verCode}
          className="can"
          width="80"
          onClick={changeVer}
          style={{ position: "absolute", bottom: "114px", right: "40px" }}
        ></canvas>
        <Form.Item>
          <Space size={40}>
            <Button type="primary" shape="round" ghost onClick={submit}>
              登&nbsp;&nbsp;&nbsp;&nbsp;陆
            </Button>

            <Button
              type="link"
              ghost
              onClick={() => {
                // console.log(form.getFieldError("username"));
                setNameErrorWord((prev) => undefined);
                setPasswordErrorWord((prev) => undefined);
                setVerficationErrorWord((prev) => undefined);
                form.resetFields();
                setfocusItem(0);
                ele.current.style.transform = "translateZ(-180px) rotateX(90deg)";
              }}
            >
              注&nbsp;&nbsp;&nbsp;&nbsp;册
            </Button>
          </Space>
        </Form.Item>
      </Form>

      <PinTu token={token} ></PinTu>
    </Card>
  );
}

export default connect(state=> state,(dispatch)=> {
  return {
    getUserInfo:(data) => dispatch(data) 
  }
})(LoginForm)